
#include "w5500.h"
#include "wizchip_conf.h"
#include "IO.h"
#include "BSP_Delay.h"

#include "FreeRTOS.h"
#include "task.h"

#include "BSP_Config.h"
#include "BSP.h"

void BSP_W5500_HwReset(void);

#if 0
#define SPI_MOSI_GPIO		GPD
#define SPI_MOSI_PIN		Pin13

#define SPI_MISO_GPIO		GPD
#define SPI_MISO_PIN		Pin14

#define SPI_SCK_GPIO		GPD
#define SPI_SCK_PIN			Pin15


static const IO_T W5500_CS = {(void*)GPD, Pin12};
static const IO_T W5500_RST = {(void*)GPD, Pin0};

static const IO_T W5500_SPI_MOSI = {(void*)SPI_MOSI_GPIO, SPI_MOSI_PIN};
static const IO_T W5500_SPI_MISO = {(void*)SPI_MISO_GPIO, SPI_MISO_PIN};
static const IO_T W5500_SPI_SCK = {(void*)SPI_SCK_GPIO, SPI_SCK_PIN};


#define SPI_MOSI_SetState(state) 	BSP_IO_Set(SPI_MOSI_GPIO, SPI_MOSI_PIN, state)
#define SPI_MISO_GetState() 		BSP_IO_Get(SPI_MISO_GPIO, SPI_MISO_PIN)
#define SPI_CLK_SetState(state) 	BSP_IO_Set(SPI_SCK_GPIO, SPI_SCK_PIN, state)


#define SPI_ExchangeBit(send, receive, num) { \
	if((send) & (0x80 >> (num))){	SPI_MOSI_SetState(1u);} \
	else{SPI_MOSI_SetState(0u);} \
	SPI_CLK_SetState(1);	\
	if(SPI_MISO_GetState()){(receive) |= (0x80 >> (num));}	\
	SPI_CLK_SetState(0); \
}


static uint8_t Spi_Exchange(uint8_t send)
{
    uint8_t receive = 0; 
    
	taskENTER_CRITICAL();
    SPI_CLK_SetState(0);
	SPI_ExchangeBit(send, receive, 0);
	SPI_ExchangeBit(send, receive, 1);
	SPI_ExchangeBit(send, receive, 2);
	SPI_ExchangeBit(send, receive, 3);
	SPI_ExchangeBit(send, receive, 4);
	SPI_ExchangeBit(send, receive, 5);
	SPI_ExchangeBit(send, receive, 6);
	SPI_ExchangeBit(send, receive, 7);
	taskEXIT_CRITICAL();

    return receive;
}
#endif 

static const IO_T W5500_RST = IO_INIT_TABLE(W5500_RST_GP, W5500_RST_PIN);

static void W5500_SPI_Init(void){
	BSP_SPI_Init(W5500_SpiId, 8 * 1000000);
	IO_Init(&W5500_RST, IO_Mode_OUT);
	BSP_W5500_HwReset();
}

static uint8_t BSP_W5500_TxRxByte(uint8_t TxByte)
{
	return BSP_SPI_Exchange(W5500_SpiId, TxByte);
}

static void BSP_W5500_CsSel(void){
	BSP_SPI_SetNSS(W5500_SpiId, 0);
}

static void BSP_W5500_CsDesel(void){
	BSP_SPI_SetNSS(W5500_SpiId, 1);
}

static uint8_t BSP_W5500_ReadByte(void){
#if 1
	return BSP_W5500_TxRxByte(0xFF);
#else
	return Spi_Exchange(0xFF);
#endif 
}

static void BSP_W5500_WriteByte(uint8_t wb){
#if 1
	BSP_W5500_TxRxByte(wb);
#else
	Spi_Exchange(wb);
#endif 
}

void BSP_W5500_Init(void){
	reg_wizchip_cs_cbfunc(BSP_W5500_CsSel, BSP_W5500_CsDesel);
	reg_wizchip_spi_cbfunc(BSP_W5500_ReadByte, BSP_W5500_WriteByte);
	W5500_SPI_Init();
}

void BSP_W5500_HwReset(void){
	IO_Set(&W5500_RST, 0);
	BSP_Delay_ms(1);
	IO_Set(&W5500_RST, 1);
	BSP_Delay_ms(1);
}


